// pages/snake/snake.js
Page({
  data: {
    score: 0, //当前得分
    maxscore: 900, //历史最高分
    startx: 0, //触摸开始的横坐标
    starty: 0, //触摸开始的纵坐标
    endx: 0, //触摸结束的横坐标
    endy: 0, //触摸结束的纵坐标
    ground: [], //存储操场的每个方块
    rows: 28, //行数
    cols: 22, //列数
    snake: [], //蛇
    food: [], //食物
    direction: "", //移动方向
    timer: "", //初始化定时器
    modalHidden: true //modal弹出窗口是否隐藏
  },

  // 小程序注册完成后，加载页面，触发onLoad方法
  onLoad: function (options) {
    // 通过getStorageSync获得缓存数据
    var maxscore = wx.getStorageSync("maxscore")
    // 如果未存储
    if (!maxscore) {
      maxscore = 0
    }
    this.setData({
      maxscore: maxscore
    })
    // 
    this.initGround(this.data.rows, this.data.cols)
    this.initSnake(3)
    this.createFood()
    this.move()
  },

  // 计分器 如果得分高于记录中的最高分
  storeScore: function () {
    if (this.data.maxscore < this.data.score) {
      this.setData({
        maxscore: this.data.score
      })
    }
    // 设置本地数据缓存
    wx.setStorageSync("maxscore", this.data.maxscore)
  },

  //初始化操场
  initGround: function (rows, cols) {
    for (var i = 0; i < rows; i++) {
      var arr = [];
      // 给数组添加元素
      this.data.ground.push(arr);
      for (var j = 0; j < cols; j++) {
        this.data.ground[i].push(0)
      }
    }
    // console.log(this.data.ground)
  },

  //初始化蛇,蛇的长度是3，宽度是1
  initSnake: function (len) {
    for (var i = 0; i < len; i++) {
      this.data.ground[0][i] = 1
      this.data.snake.push([0, i])
    }
    // console.log(this.data.snake)
  },

  //创建食物
  createFood: function () {
    // 取整
    var x = Math.floor(Math.random() * this.data.rows)
    var y = Math.floor(Math.random() * this.data.cols)
    var ground = this.data.ground
    var snake = this.data.snake
    // 食物这一块标为3，用来区别空白和蛇
    ground[x][y] = 3
    // 防止食物和小蛇重合
    for (var i = 0; i < snake.length; i++) {
      // snake
      var node = snake[i][1]
      // console.log(node)
      // 如果食物坐标和蛇重合
      if (x == 0 && y == node) {
        createFood()
        return
      } else {
        // 如果不重叠
        this.setData({
          // 重新赋值
          ground: ground,
          food: [x, y]
        })
      }
    }
  },

  //手指触摸开始
  tapStart: function (e) {
    // console.log("开始点击")
    // console.log(e)
    this.setData({
      // 获取手指的方位
      startx: e.touches[0].pageX,
      starty: e.touches[0].pageY
    })
  },

  //手指触摸移动
  tapMove: function (e) {
    // console.log("移动")
    // console.log(e)
    this.setData({
      endx: e.touches[0].pageX,
      endy: e.touches[0].pageY
    })
  },

  //手指触摸结束
  tapEnd: function () {
    //获取滑动距离
    var heng = (this.data.endx) ? (this.data.endx - this.data.startx) : 0
    var zong = (this.data.endy) ? (this.data.endy - this.data.starty) : 0
    // 通过估量判断是否为手指滑动
    if (Math.abs(heng) > 5 || Math.abs(zong) > 5) {
      // 先分上下，左右；再调用computerDir()来判断具体方向
      var direction = Math.abs(heng) > Math.abs(zong) ? this.computerDir(1, heng) : this.computerDir(0, zong)
      switch (direction) {
        // 如果往左
        case "left":
          // 如果此时方向为往右，就跳出
          if (this.data.direction == "right") {
            return;
          }
          // 如果没问题就break
          break;
        case "right":
          if (this.data.direction == "left") {
            return
          }
          break;
        case "top":
          if (this.data.direction == "bottom") {
            return
          }
          break;
        case "bottom":
          if (this.data.direction == "top") {
            return
          }
          break;
      }
      this.setData({
        direction: direction,
        startx: 0,
        starty: 0,
        endx: 0,
        endy: 0
      })
    }
    // console.log(this.data.direction)
  },

  //判断滑动方向
  computerDir: function (heng, num) {
    // 如果heng = 1 不为0
    if (heng) {
      return (num > 0) ? "right" : "left"
    } else {
      return (num > 0) ? "bottom" : "top"
    }
  },

  //移动函数
  move: function () {
    var that = this
    // 设置定时器
    this.data.timer = setInterval(function () {
      that.changeDirection(that.data.direction)
      that.setData({
        ground: that.data.ground
      })
      // 设置速度
    }, 300)
  },

  //改变方向
  changeDirection: function (dir) {
    switch (dir) {
      case "left":
        return this.changeLeft();
        break;
      case "right":
        return this.changeRight();
        break;
      case "top":
        return this.changeTop();
        break;
      case "bottom":
        return this.changeBottom();
        break;
    }
  },

  //改变方向向左
  changeLeft: function () {
    var arr = this.data.snake;
    var len = this.data.snake.length;
    // 2
    var snakeHEAD = arr[len - 1][1]
    // 蛇的长度，尾部
    var snakeTAIL = arr[0]
    var ground = this.data.ground
    // 小蛇尾部的横坐标和纵坐标空出来
    ground[snakeTAIL[0]][snakeTAIL[1]] = 0
    // 通过for循环往前挪一格
    for (var i = 0; i < len - 1; i++) {
      arr[i] = arr[i + 1]
    }
    // 蛇尾的横坐标
    var x = arr[len - 1][0]
    // 蛇尾的列坐标
    var y = arr[len - 1][1] - 1
    arr[len - 1] = [x, y]
    this.checkGame(snakeTAIL)
    for (var i = 1; i < len; i++) {
      // 横纵坐标
      ground[arr[i][0]][arr[i][1]] = 1
    }
    // 重新赋值
    this.setData({
      ground: ground,
      snake: arr
    })
    // 照应前面的return
    return true
  },

  //改变方向向右
  changeRight: function () {
    var arr = this.data.snake;
    var len = this.data.snake.length;
    var snakeHEAD = arr[len - 1][1]
    var snakeTAIL = arr[0]
    var ground = this.data.ground
    ground[snakeTAIL[0]][snakeTAIL[1]] = 0
    for (var i = 0; i < len - 1; i++) {
      arr[i] = arr[i + 1]
    }
    var x = arr[len - 1][0]
    // 行+1 
    var y = arr[len - 1][1] + 1
    arr[len - 1] = [x, y]
    this.checkGame(snakeTAIL)
    for (var i = 1; i < len; i++) {
      ground[arr[i][0]][arr[i][1]] = 1
    }
    this.setData({
      ground: ground,
      snake: arr
    })
    return true
  },

  //改变方向向上
  changeTop: function () {
    var arr = this.data.snake;
    var len = this.data.snake.length;
    var snakeHEAD = arr[len - 1][1]
    var snakeTAIL = arr[0]
    var ground = this.data.ground
    ground[snakeTAIL[0]][snakeTAIL[1]] = 0
    for (var i = 0; i < len - 1; i++) {
      arr[i] = arr[i + 1]
    }
    var x = arr[len - 1][0] - 1
    var y = arr[len - 1][1]
    arr[len - 1] = [x, y]
    this.checkGame(snakeTAIL)
    for (var i = 1; i < len; i++) {
      ground[arr[i][0]][arr[i][1]] = 1
    }
    this.setData({
      ground: ground,
      snake: arr
    })
    return true
  },

  //改变方向向下
  changeBottom: function () {
    var arr = this.data.snake;
    var len = this.data.snake.length;
    var snakeHEAD = arr[len - 1][1]
    var snakeTAIL = arr[0]
    var ground = this.data.ground
    ground[snakeTAIL[0]][snakeTAIL[1]] = 0
    for (var i = 0; i < len - 1; i++) {
      arr[i] = arr[i + 1]
    }
    var x = arr[len - 1][0] + 1
    var y = arr[len - 1][1]
    arr[len - 1] = [x, y]
    this.checkGame(snakeTAIL)
    for (var i = 1; i < len; i++) {
      ground[arr[i][0]][arr[i][1]] = 1
    }
    this.setData({
      ground: ground,
      snake: arr
    })
    return true
  },

  //游戏状态
  checkGame: function (snakeTAIL) {
    var arr = this.data.snake;
    // 蛇的长度
    var len = this.data.snake.length;
    // [0,2]
    var snakeHEAD = arr[len - 1]
    // 行<0 或者 大于行数28 ｜｜ 列数<0 或者 列数 大于等于22
    if (snakeHEAD[0] < 0 || snakeHEAD[0] >= this.data.rows || snakeHEAD[1] < 0 || snakeHEAD[1] >= this.data.cols) {
      clearInterval(this.data.timer)
      this.setData({
        modalHidden: false
      })
    }
    for (var i = 0; i < len - 1; i++) {
      // 蛇撞到了本身，即列相等的同时 行也相等
      if (snakeHEAD[0] == arr[i][0] && snakeHEAD[1] == arr[i][1]) {
        clearInterval(this.data.timer)
        this.setData({
          modalHidden: false
        })
      }
    }
    // 蛇的列与食物的列相等 同时 蛇的行与食物的行相等
    if (snakeHEAD[0] == this.data.food[0] && snakeHEAD[1] == this.data.food[1]) {
      // unshift() 方法可向数组的开头添加一个或更多元素，并返回新的长度。
      arr.unshift(snakeTAIL)
      this.setData({
        score: this.data.score + 10
      })
      this.createFood()
      this.storeScore()
    }
  },

  //点击确定触发的事件，清空
  modalConfirm: function () {
    this.setData({
      score: 0,
      ground: [],
      snake: [],
      food: [],
      modalHidden: true,
      direction: ""
    })
    this.onLoad()
  }

})